package ucd.csi.comp30220.fall2011.oteop.airline.impl;

import java.util.Date;
import java.util.StringTokenizer;

import org.mortbay.jetty.client.ContentExchange;
import org.mortbay.jetty.client.HttpClient;

import javax.servlet.http.HttpServletResponse;

import ucd.csi.comp30220.fall2011.oteop.OTEOP;
import ucd.csi.comp30220.fall2011.oteop.airline.Airline;
import ucd.csi.comp30220.fall2011.oteop.airline.AirlineException;
import ucd.csi.comp30220.fall2011.oteop.airline.AirlineInfo;
import ucd.csi.comp30220.fall2011.oteop.util.EndPoint;
import ucd.csi.comp30220.fall2011.oteop.util.ServiceFinder;

public class AirlineClient implements Airline {
    
    private HttpClient client;
    private String url;
    
    public AirlineClient(final String code, long timeout) throws Exception {
        EndPoint endPoint = ServiceFinder.findService(
            OTEOP.JMDNS_TYPE_TCP_LOCAL, Airline.JMDNS_SUB_TYPE, code, timeout);
        
        if (endPoint == null)
            throw new Exception("Failed to get Airline in " +timeout +"ms");
        
        String host = endPoint.getHost();
        int port = endPoint.getPort();
        url = "http://" +host +":" +port;
        
        client = new HttpClient();
        client.start();
    }

    public AirlineInfo getInfo() throws AirlineException {
        try {
            ContentExchange exchange = new ContentExchange(true);
            exchange.setMethod("GET");
            exchange.setURL(url);
            client.send(exchange);
            exchange.waitForDone();
            if (exchange.getResponseStatus() != HttpServletResponse.SC_OK) {
                throw new AirlineException(
                    "Unexpected response from AirlineServer [" 
                    + exchange.getResponseStatus() +"] " + exchange.getResponseContent(), null);
            }
            StringTokenizer st = new StringTokenizer(
                exchange.getResponseContent().replace('\n',' ').trim(), "|");
            return new AirlineInfo(st.nextToken(), st.nextToken());
        } catch (Exception e) {
            throw new AirlineException("Failed to connect to AirlineServer", e);
        }
    }

    private void invoke(String method, String flightNumber, String airportCode, Date dateTime) throws AirlineException {
        try {
            ContentExchange exchange = new ContentExchange(true);
            exchange.setMethod("PUT");
            exchange.setURL(url +"/"
                + "?method=" +method
                + "&flightNumber=" +flightNumber 
                + "&airportCode=" +airportCode 
                + "&dateTime=" +dateTime.getTime() );
            client.send(exchange);
            exchange.waitForDone();
            if (exchange.getResponseStatus() != HttpServletResponse.SC_OK) {
                throw new AirlineException(
                    "Unexpected response from AirlineServer [" 
                    + exchange.getResponseStatus() +"] " + exchange.getResponseContent(), null);
            }
        } catch (Exception e) {
            throw new AirlineException("Failed to connect to AirlineServer", e);
        }
    }

    public void flightDeparted(String flightNumber, String airportCode, Date dateTime) throws AirlineException {
        invoke("flightDeparted", flightNumber, airportCode, dateTime);
    }
    
    public void flightLanded(String flightNumber, String airportCode, Date dateTime) throws AirlineException {
        invoke("flightLanded", flightNumber, airportCode, dateTime);
    }
}
